home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
BCI NET
/
BCI NET Dec 94.iso
/
archives
/
programming
/
c
/
gcc261ud-c.lha
/
gnu
/
ManualBrowser
/
main.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-09-06
|
16KB
|
606 lines
/************************************************************************/
/* */
/* Copyright (C) 1994 Christian Stieber */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 2 of the License, or */
/* (at your option) any later version. */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program; if not, write to the Free Software */
/* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
/* */
/************************************************************************/
/* */
/* Author address: */
/* Christian Stieber */
/* Konradstraße 41 */
/* D-85055 Ingolstadt */
/* (Germany) */
/* Phone: 0841-59896 */
/* */
/************************************************************************/
#ifndef V39
#define CreatePool LibCreatePool
#define DeletePool LibDeletePool
#define AllocPooled LibAllocPooled
#define FreePooled LibFreePooled
#endif
#ifndef DOS_DOSEXTENS_H
#include <dos/dosextens.h>
#endif
#ifndef DOS_EXALL_H
#include <dos/exall.h>
#endif
#ifndef INTUITION_INTUITION_H
#include <intuition/intuition.h>
#endif
#ifndef LIBRARIES_AMIGAGUIDE_H
#include <libraries/amigaguide.h>
#endif
#ifndef WORKBENCH_STARTUP_H
#include <workbench/startup.h>
#endif
#ifndef WORKBENCH_WORKBENCH_H
#include <workbench/workbench.h>
#endif
#ifndef __GNUC__
#ifndef CLIB_EXEC_PROTOS_H
#include <clib/exec_protos.h>
#endif
#ifndef CLIB_DOS_PROTOS_H
#include <clib/dos_protos.h>
#endif
#ifndef CLIB_UTILITY_PROTOS_H
#include <clib/utility_protos.h>
#endif
#ifndef CLIB_INTUITION_PROTOS_H
#include <clib/intuition_protos.h>
#endif
#ifndef CLIB_ICON_PROTOS_H
#include <clib/icon_protos.h>
#endif
#ifndef CLIB_AMIGAGUIDE_PROTOS_H
#include <clib/amigaguide_protos.h>
#endif
#include <pragmas/exec_pragmas.h>
#include <pragmas/dos_pragmas.h>
#include <pragmas/intuition_pragmas.h>
#include <pragmas/utility_pragmas.h>
#include <pragmas/icon_pragmas.h>
#include <pragmas/amigaguide_pragmas.h>
#endif
#include <string.h>
#include "Globals.h"
/***********************************************/
struct DosLibrary *DOSBase;
struct IntuitionBase *IntuitionBase;
struct Library *AmigaGuideBase;
struct Library *UtilityBase;
/***********************************************/
#ifdef __GNUC__
#include "Inlines.h"
#ifndef V39
APTR AllocPooled(APTR, ULONG);
void FreePooled(APTR, APTR, ULONG);
APTR CreatePool(ULONG, ULONG, ULONG);
void DeletePool(APTR);
#endif
#endif /* __GNUC__ */
/***********************************************/
#define CONFIGFILE "ManualBrowser.config"
/***********************************************/
char Version[]="$VER: ManualBrowser " PROGVERSION " (" PROGDATE ")"
#ifdef V39
"(V39) "
#endif
"(" CPU ") "
"© 1994 Christian Stieber";
/***********************************************/
#define BASENAME "ManBrowser"
#define PUDDLESIZE (20*1024)
/***********************************************/
void *MemoryPool;
struct ActionNode *ActionList;
BPTR ManDir;
long LineLength=70;
char DatabaseName[64];
/***********************************************/
static AMIGAGUIDEHOST AmigaGuideHostHandle;
static AMIGAGUIDECONTEXT AmigaGuideHandle;
static char Filename[64];
static BPTR FileHandle;
static struct WBStartup *WBStartupMessage;
static struct EasyStruct EasyStruct=
{
5*4,
0,
"Manual browser " PROGVERSION " error",
NULL,
NULL
};
/***********************************************/
#ifdef __GNUC__
static void MyExit(int) __attribute__((noreturn));
#endif
static void MyExit(int RC)
{
if (WBStartupMessage)
{
Forbid();
ReplyMsg((struct Message *)WBStartupMessage);
}
exit(RC);
}
/***********************************************/
static int DisplayError(char *Action, char *Format,...)
{
if (WBStartupMessage)
{
EasyStruct.es_TextFormat=Format;
EasyStruct.es_GadgetFormat=Action;
return EasyRequestArgs(NULL,&EasyStruct,NULL,(&Format)+1);
}
else
{
VPrintf(Format,(&Format)+1);
PutStr("\n");
return 0;
}
/* not reached */
}
/***********************************************/
static int DisplayDosError(char *Action, char *Filename)
{
if (WBStartupMessage)
{
char Buffer[256];
char *t;
t=Buffer;
Fault(IoErr(),Filename,t,sizeof(Buffer));
EasyStruct.es_TextFormat="%s";
EasyStruct.es_GadgetFormat=Action;
return EasyRequestArgs(NULL,&EasyStruct,NULL,&t);
}
else
{
PrintFault(IoErr(),Filename);
return 0;
}
/* not reached */
}
/***********************************************/
#ifdef __GNUC__
static void CloseAll(int) __attribute__((noreturn));
#endif
static void CloseAll(int RC)
{
if (AmigaGuideHandle) CloseAmigaGuide(AmigaGuideHandle);
if (AmigaGuideHostHandle)
{
while (RemoveAmigaGuideHostA(AmigaGuideHostHandle,NULL))
{
Delay(TICKS_PER_SECOND);
}
}
if (FileHandle)
{
DeleteFile(Filename);
}
if (ManDir) UnLock(ManDir);
if (MemoryPool) DeletePool(MemoryPool);
CloseLibrary(AmigaGuideBase);
CloseLibrary(UtilityBase);
CloseLibrary((struct Library *)IntuitionBase);
CloseLibrary((struct Library *)DOSBase);
MyExit(RC);
}
/***********************************************/
static void InitThings(void)
{
struct Process *MyProcess;
MyProcess=(struct Process *)FindTask(NULL);
if (MyProcess->pr_CLI)
{
WBStartupMessage=NULL;
}
else
{
do
{
WaitPort(&MyProcess->pr_MsgPort);
}
while (!(WBStartupMessage=(struct WBStartup *)GetMsg(&MyProcess->pr_MsgPort)));
}
#ifdef V39
if (!(DOSBase=(struct DosLibrary *)OpenLibrary("dos.library",39)))
#else
if (!(DOSBase=(struct DosLibrary *)OpenLibrary("dos.library",37)))
#endif
{
MyExit(100);
}
if (!(IntuitionBase=(struct IntuitionBase *)OpenLibrary("intuition.library",37)))
{
CloseLibrary((struct Library *)DOSBase);
MyExit(100);
}
if (!(UtilityBase=OpenLibrary("utility.library",37)))
{
DisplayError("Quit","Unable to open utility.library V37");
CloseAll(RETURN_FAIL);
}
if (!(AmigaGuideBase=OpenLibrary("amigaguide.library",34)))
{
DisplayError("Quit","Unable to open amigaguide.library V34");
CloseAll(RETURN_FAIL);
}
if (!(MemoryPool=CreatePool(0,PUDDLESIZE,PUDDLESIZE)))
{
DisplayError("Quit","Unable to create memory pool");
CloseAll(RETURN_FAIL);
}
}
/***********************************************/
static void AddDatabase(void)
{
#ifdef __GNUC__
static struct Hook AmigaGuideHook=
{
{NULL,NULL},
HookEntryA1,
AmigaGuideHostDispatcher,
NULL
};
#else
static struct Hook AmigaGuideHook=
{
{NULL,NULL},
AmigaGuideHostDispatcher,
NULL,
NULL
};
#endif
char *t;
Sprintf(DatabaseName,BASENAME ".%lx",FindTask(NULL));
Sprintf(Filename,"t:%s.guide",DatabaseName);
if (!(FileHandle=Open(Filename,MODE_NEWFILE)))
{
DisplayDosError("Quit",Filename);
CloseAll(RETURN_ERROR);
}
t=DatabaseName;
if (VFPrintf(FileHandle,"@database %s.guide\n"
"@node EnItSiRhC\n"
"@endnode\n",&t)==-1)
{
DisplayDosError("Quit",Filename);
Close(FileHandle);
CloseAll(RETURN_ERROR);
}
Close(FileHandle);
if (!(AmigaGuideHostHandle=AddAmigaGuideHostA(&AmigaGuideHook,DatabaseName,NULL)))
{
DisplayError("Quit","Unable to add dynamic amiga guide host");
CloseAll(RETURN_FAIL);
}
}
/***********************************************/
static void OpenDatabase(void)
{
struct NewAmigaGuide NewAmigaGuide;
NewAmigaGuide.nag_Lock=NULL;
NewAmigaGuide.nag_Name=Filename;
NewAmigaGuide.nag_Screen=NULL;
NewAmigaGuide.nag_PubScreen=NULL;
NewAmigaGuide.nag_HostPort=NULL;
NewAmigaGuide.nag_ClientPort=BASENAME;
NewAmigaGuide.nag_BaseName=BASENAME;
NewAmigaGuide.nag_Flags=HTF_NOACTIVATE;
NewAmigaGuide.nag_Context=NULL;
NewAmigaGuide.nag_Node=NULL;
NewAmigaGuide.nag_Line=0;
NewAmigaGuide.nag_Extens=NULL;
NewAmigaGuide.nag_Client=NULL;
if (!(AmigaGuideHandle=OpenAmigaGuideA(&NewAmigaGuide,NULL)))
{
DisplayError("Quit","Unable to open amiga guide database");
CloseAll(RETURN_FAIL);
}
}
/***********************************************/
#ifdef __GNUC__
#define ICONBASE IconBase,
#else
#define ICONBASE
#endif
static void GetParams(void)
{
if (WBStartupMessage)
{
struct Library *IconBase;
if ((IconBase=OpenLibrary("icon.library",33)))
{
if (WBStartupMessage->sm_NumArgs)
{
BPTR OldCurrDir;
struct DiskObject *DiskObject;
OldCurrDir=CurrentDir(WBStartupMessage->sm_ArgList[0].wa_Lock);
if ((DiskObject=GetDiskObject(ICONBASE WBStartupMessage->sm_ArgList[0].wa_Name)))
{
char *ManPath;
if (!((ManPath=FindToolType(ICONBASE (UBYTE **)DiskObject->do_ToolTypes,"MANUALDIR")) ||
(ManPath=FindToolType(ICONBASE (UBYTE **)DiskObject->do_ToolTypes,"MANDIR")) ||
(ManPath=FindToolType(ICONBASE (UBYTE **)DiskObject->do_ToolTypes,"DIR"))))
{
ManPath="man:";
}
if (!(ManDir=Lock(ManPath,SHARED_LOCK)))
{
DisplayDosError("Quit",ManPath);
}
FreeDiskObject(ICONBASE DiskObject);
}
CurrentDir(OldCurrDir);
}
CloseLibrary(IconBase);
}
}
else
{
struct
{
char *ManualDir;
} Arguments;
struct RDArgs *RDArgs;
Arguments.ManualDir="man:";
if (!(RDArgs=ReadArgs("MANUALDIR=MANDIR=DIR",(long *)&Arguments,NULL)))
{
PrintFault(IoErr(),NULL);
CloseAll(RETURN_FAIL);
}
if (!(ManDir=Lock(Arguments.ManualDir,SHARED_LOCK)))
{
DisplayDosError("Quit",Arguments.ManualDir);
}
FreeArgs(RDArgs);
}
if (!ManDir)
{
CloseAll(RETURN_FAIL);
}
}
/***********************************************/
static void ReadConfigFile(BPTR ConfigFile, char *Filename)
{
BPTR OldInput;
OldInput=SelectInput(ConfigFile);
while (TRUE)
{
struct
{
char *Pattern;
char *Action;
} CurrentLine;
struct RDArgs *LineArgs;
while (TRUE)
{
int Character;
Character=FGetC(ConfigFile);
if (Character!='\n' && Character!=' ' && Character!='\t')
{
if (Character==-1)
{
if (IoErr())
{
DisplayDosError("Quit",Filename);
Close(ConfigFile);
CloseAll(RETURN_ERROR);
}
goto Done;
}
UnGetC(ConfigFile,Character);
break;
}
}
CurrentLine.Pattern=NULL;
CurrentLine.Action=NULL;
if ((LineArgs=ReadArgs("P/A,A/A/F",(long *)&CurrentLine,NULL)))
{
struct ActionNode *ActionNode;
int AllocSize, PatternSize;
PatternSize=2*strlen(CurrentLine.Pattern);
AllocSize=sizeof(struct ActionNode)+strlen(CurrentLine.Action)+PatternSize;
if ((ActionNode=AllocPooled(MemoryPool,AllocSize)))
{
ActionNode->Pattern=Stpcpy(ActionNode->Action,CurrentLine.Action)+1;
if (ParsePatternNoCase(CurrentLine.Pattern,ActionNode->Pattern,PatternSize)!=-1)
{
ActionNode->Next=ActionList;
ActionList=ActionNode;
}
else
{
FreePooled(MemoryPool,ActionNode,AllocSize);
if (!DisplayError("Ignore|Quit","Error in pattern: %s",CurrentLine.Pattern))
{
ActionNode=NULL;
}
}
}
else
{
DisplayDosError("Quit",NULL);
}
FreeArgs(LineArgs);
if (!ActionNode)
{
Close(ConfigFile);
CloseAll(RETURN_ERROR);
}
}
else
{
if (!DisplayDosError("Ignore line|Quit",NULL))
{
Close(ConfigFile);
CloseAll(RETURN_ERROR);
}
}
}
/* Not reached */
Done:
SelectInput(OldInput);
}
/***********************************************/
#define CONFIGPATHLEN 4096
static void ReadConfig(void)
{
static char *ConfigFile[]=
{
"PROGDIR:" CONFIGFILE,
"S:" CONFIGFILE,
"ENV:" CONFIGFILE
};
int i;
for (i=0; i<3; i++)
{
BPTR FileHandle;
if ((FileHandle=Open(ConfigFile[i],MODE_OLDFILE)))
{
char *Filename, *t;
Filename=ConfigFile[i];
if ((t=AllocPooled(MemoryPool,CONFIGPATHLEN)))
{
if (NameFromFH(FileHandle,t,CONFIGPATHLEN))
{
Filename=t;
}
}
ReadConfigFile(FileHandle,Filename);
if (t)
{
FreePooled(MemoryPool,t,CONFIGPATHLEN);
}
Close(FileHandle);
}
}
}
#undef CONFIGPATHLEN
/***********************************************/
void Main(void);
void Main(void)
{
InitThings();
GetParams();
ReadConfig();
AddDatabase();
OpenDatabase();
CloseAll(RETURN_OK);
/* Not reached */
}